// keypad.c - 修改后的键盘模块代码
#include <nvs.h>
#include <nvs_flash.h>
#include "keypad.h"
#include "esp_log.h"
#include "utils/i2c/i2c_master/i2c_master_utils.h"
#include "system_init/system_init.h"
static const char* NVS_NAMESPACE = "keypad_config";
static const char* ADDR_KEY = "keypad_addr";
static uint8_t default_keypad_addr = 0x27; // 默认I2C地址
static const char* TAG = "KEYPAD";
static QueueHandle_t event_queue = NULL;
static uint8_t cached_keypad_addr = 0;    // 缓存的键盘模块地址
static bool addr_cached = false;          // 地址是否已缓存的标志
// 获取键盘模块地址（优先使用缓存的地址）
uint8_t keypad_get_module_addr(void) {
    if (addr_cached) {
        return cached_keypad_addr;
    }

    nvs_handle_t my_handle;
    uint8_t addr;
    esp_err_t err;

    // 打开
    err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &my_handle);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Error (%s) opening NVS handle!\n", esp_err_to_name(err));
        addr = default_keypad_addr;
    } else {
        // 读取保存的地址
        err = nvs_get_u8(my_handle, ADDR_KEY, &addr);
        nvs_close(my_handle);

        switch (err) {
            case ESP_OK:
                ESP_LOGI(TAG, "Keypad address loaded from NVS: 0x%02X", addr);
                break;
            case ESP_ERR_NVS_NOT_FOUND:
                ESP_LOGW(TAG, "Keypad address not found in NVS, using default: 0x%02X", default_keypad_addr);
                addr = default_keypad_addr;
                break;
            default :
                ESP_LOGE(TAG, "Error (%s) reading keypad address from NVS!", esp_err_to_name(err));
                addr = default_keypad_addr;
                break;
        }
    }

    // 缓存地址
    cached_keypad_addr = addr;
    addr_cached = true;

    return addr;
}

// 设置并保存键盘模块地址
esp_err_t keypad_set_module_addr(uint8_t addr) {
    nvs_handle_t my_handle;
    esp_err_t err;

    // 打开
    err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &my_handle);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Error (%s) opening NVS handle for writing!", esp_err_to_name(err));
        return err;
    }

    // 保存地址
    err = nvs_set_u8(my_handle, ADDR_KEY, addr);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Error (%s) setting keypad address in NVS!", esp_err_to_name(err));
    } else {
        // 提交
        err = nvs_commit(my_handle);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "Error (%s) committing keypad address to NVS!", esp_err_to_name(err));
        } else {
            // 更新缓存的地址
            cached_keypad_addr = addr;
            addr_cached = true;
            ESP_LOGI(TAG, "Keypad address saved to NVS: 0x%02X", addr);
        }
    }

    // 关闭
    nvs_close(my_handle);
    return err;
}

// 读取PCF8574模块数据
static esp_err_t read_pcf8574(uint8_t* data) {
    uint8_t addr = keypad_get_module_addr(); // 从NVS获取地址
    esp_err_t err;
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (addr << 1) | I2C_MASTER_READ, true);
    i2c_master_read_byte(cmd, data, I2C_MASTER_NACK);
    i2c_master_stop(cmd);
    err = i2c_master_cmd_begin(I2C_MASTER_PORT_NUM, cmd, pdMS_TO_TICKS(1000));
    i2c_cmd_link_delete(cmd);
    return err;
}

// 按键处理任务
static void keypad_task(void* arg) {
    uint8_t prev_data = 0xFF;
    while (1) {
        uint8_t data;
        if (read_pcf8574(&data) == ESP_OK) {
            for (int i = 0; i < 8; i++) {
                if ((data & (1 << i)) != (prev_data & (1 << i))) {
                    // 消抖处理
                    vTaskDelay(pdMS_TO_TICKS(20)); // 延时 20 毫秒
                    uint8_t debounce_data;
                    if (read_pcf8574(&debounce_data) == ESP_OK) {
                        if ((debounce_data & (1 << i)) == (data & (1 << i))) {
                            keypad_event_t event = {
                                    .pin = i,
                                    .state = (data & (1 << i))? 0 : 1
                            };
                            xQueueSend(event_queue, &event, portMAX_DELAY);
                        }
                    }
                }
            }
            prev_data = data;
        }
        vTaskDelay(pdMS_TO_TICKS(10)); // 缩短轮询间隔为 10 毫秒
    }
}

int keypad_init(void) {
    // 初始化系统（包括NVS）
    esp_err_t err = system_init();
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "System initialization failed for relay");
        return err;
    }

    // 初始化I2C
    err = i2c_master_init();
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "I2C initialization failed for keypad");
        return err;
    }

    event_queue = xQueueCreate(10, sizeof(keypad_event_t));
    xTaskCreate(keypad_task, "keypad_task", 2048, NULL, 5, NULL);
    return ESP_OK;
}

QueueHandle_t keypad_get_event_queue(void) {
    return event_queue;
}